# -*- coding: utf-8 -*- 
# @Time : 2023/6/18 16:37 
# @Author : gkm
# @File : file.py
import json
import requests
from django.forms import model_to_dict
from django.shortcuts import render, HttpResponse
from django.urls import reverse
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

from web.forms.file import FolderModelForm, FileModelForm
from web import models

from utils.tencent.cos import delete_file, delete_file_list, credential


def file(request, project_id):
    '''文件列表&添加文件'''
    parent_object = None
    folder_id = request.GET.get('folder', "")
    if folder_id.isdecimal():
        parent_object = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                             project=request.tracer.project).first()
    # GET形式查看页面
    if request.method == 'GET':
        breadcrumb_list = []
        parent = parent_object.parent
        while parent:
            # breadcrumb_list.insert(0, {'id': parent.id, 'name': parent.name})
            breadcrumb_list.insert(0, model_to_dict(parent, ['id', 'name']))
            parent = parent.parent
        # 当前目录下的所有文件&文件夹所有获取
        queryset = models.FileRepository.objects.filter(project=request.tracer.project)
        if parent_object:
            # 进入某个目录
            file_object_list = queryset.filter(parent=parent_object).order_by('-file_type')
        else:
            # 在根目录下
            file_object_list = queryset.filter(parent__isnull=True).order_by('-file_type')

        form = FolderModelForm(request, parent_object)
        context = {
            "form": form,
            "file_object_list": file_object_list,
            "breadcrumb_list": breadcrumb_list,
            "folder_object": parent_object
        }
        return render(request, 'file.html', context)

    # POST 添加文件夹 & 文件夹的修改
    fid = request.GET.get('fid', '')
    edit_object = None
    if fid.isdecimal():
        edit_object = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                           project=request.tracer.project).first()

    if edit_object:
        form = FolderModelForm(request, parent_object, data=request.POST, instance=edit_object)
    else:
        form = FolderModelForm(request, parent_object, data=request.POST)

    # 添加文件
    form = FolderModelForm(request, parent_object, data=request.POST)
    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.file_type = request.tracer.file_type
        form.instance.update_user = request.tracer.user
        form.instance.parent = parent_object
        form.save()

        return JsonResponse({'status': True})

    return JsonResponse({'status': False, 'error': form.errors})


def file_delete(request, project_id):
    '''删除文件'''
    fid = request.GET.get('fid')

    delete_object = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()
    if delete_object.file_type == 1:
        # 删除文件，（数据库中的文件， COS存储桶中的文件，并且将已使用的文件容量返还回去）
        request.tracer.project.use_space -= delete_object.file_size
        request.tracer.project.save()
        # 删除cos文件
        delete_file(request.tracer.project.bucket, request.tracer.project.region, delete_object.key)
        delete_object.delete()

        return JsonResponse({'status': True})
    # 删除文件夹，找到文件夹下的所有文件->数据库中文件，cos文件删除，并且将已使用的文件容量返还回去

    total_size = 0
    folder_list = [delete_object, ]
    key_list = []
    for folder in folder_list:
        child_list = models.FileRepository.objects.filter(project=request.tracer.project, parent=folder).order_by(
            '-file_type')
        for child in child_list:
            if child.file_type == '2':
                folder_list.append(child)
            else:
                # 文件大小
                total_size += child.file_size
                # 删除文件
                key_list.append({"Key": child.key})
    # cos批量删除文件
    if key_list:
        delete_file_list(request.tracer.project.bucket, request.tracer.project.region, key_list)
    # 归还容量
    if total_size:
        request.tracer.project.use_space -= total_size
        request.tracer.project.save()
    # 删除数据库文件
    delete_object.delete()
    return JsonResponse({'status': True})


@csrf_exempt
def cos_credential(request, project_id):
    '''获取COS上床临时凭证'''
    per_file_limit = request.tracer.price_policy.per_file_size * 1024 * 1024
    total_size = 0
    file_list = json.loads(request.body.decode('utf-8'))
    total_file_limit = request.tracer.price_policy.project_space * 1024 * 1024 * 1024
    for item in file_list:
        # 文件的字节大小   B
        # 单文件限制      M
        # 总容量限制
        if item.size > per_file_limit:
            msg = "单文件超出限制(最大{}M)，文件{}，请购买套餐。".format(request.tracer.price_policy.per_file_size,
                                                                      item['name'])
            return JsonResponse({'status': False, 'error': msg})
        total_size += item['size']
    # 判断项目总量限制，将项目已使用的空间与添加项目空间做加法与允许存储空间作比较
    if request.tracer.project.use_space + total_size > total_file_limit:
        return JsonResponse({'status': False, 'error': "容量超限，请购买套餐。"})
    data_dict = credential(request.tracer.project.bucket, request.tracer.project.region)
    return JsonResponse({'status': True, 'data': data_dict})


@csrf_exempt
def file_post(request, project_id):
    '''文件上传成功写入数据库'''
    form = FileModelForm(request, data=request.POST)
    if form.is_valid():
        data_dict = form.cleaned_data
        data_dict.pop('etag')
        data_dict.update({'project': request.tracer.project, 'file_type': 1, 'update_user': request.tracer.user})
        instance = models.FileRepository.objects.create(**data_dict)

        # 更新项目已使用空间
        request.tracer.project.use_space += data_dict['file_size']
        request.tracer.project.save()

        result = {
            'id': instance.id,
            'file_size': instance.size,
            'username': instance.update_user.username,
            'datetime': instance.update_datetime.strftime("%Y年%m月%d日 %H:%M"),
            'download': reverse('file_download', kwargs={'project_id': project_id, 'file_id': instance.id})
            # 'file_type': instance.get_file_type_display()
        }
        return JsonResponse({'status': True, 'data': result})
    return JsonResponse({'status': False, 'data': '文件错误'})


def file_download(request, project_id, file_id):
    '''下载文件'''

    file_object = models.FileRepository.objects.filter(id=file_id, project_id=project_id).first()
    res = requests.get(file_object.file_path)
    # 文件分块处理
    data = res.iter_content()

    response = HttpResponse(data, content_type='application/octet-stream')

    from django.utils.encoding import escape_uri_path
    # 设置响应头，中文文件名转义
    response['Content-Disposition'] = "attachment; filename{};".format(escape_uri_path(file_object.name))
    return response
